package IC.asm.printer;


import java.util.List;

import IC.asm.*;
import IC.asm.Instruction.Ops;
import IC.asm.operands.*;

public class AttPrinter extends ASMPrinter {

	public AttPrinter() {};

	public static void Print(List<ASMEntry> asm) {
		AttPrinter p = new AttPrinter();
		System.out.println(".att_syntax prefix");
		for (ASMEntry e: asm) {
			System.out.println(e.accept(p, null));
		}
	}

	public String visit(Instruction that, Object d) {
		StringBuffer s = new StringBuffer();
		s.append("\t");
		s.append(that.getOp());
		if(Instruction.Ops.NeedSizeOps.contains(that.getOp())) {
			s.append("l");
		}
		s.append("\t\t");
		if (Instruction.Ops.ControlFlowOps.contains(that.getOp())) {
			s.append(that.getSource().accept(this, ""));
		}
		else {
			if (that.getSource() != null) {
				s.append(that.getSource().accept(this, null));
				if (that.getDest() != null)
					s.append(", ");
			}
			if (that.getDest() != null) {
				s.append(that.getDest().accept(this, null));
			}
		}
		if (!that.getSideEffects().isEmpty()) {
			s.append("\t\t#");
			for (MachineReg.Regs reg : that.getSideEffects()) {
				s.append(" "+reg);
			}
		}
		return s.toString();
	}

	public String visit(MemOperand that, Object d) {
		StringBuffer s = new StringBuffer();

		if (d != null) s.append("*");

		if (that.getOffset() != 0) {
			s.append(that.getOffset());
		}
		s.append("(");

		s.append(that.getBase().accept(this, null));
		
		if (that.getIndex() != null) {
			s.append(", ");
			s.append(that.getIndex().accept(this, null));
		}
		if (that.getScale() != 1) {
			s.append(", ");
			s.append(that.getScale());
		}
		s.append(")");
		return s.toString();
	}


	public String visit(MachineReg that, Object d) {
		return "%"+that.getReg().toString();
	}

	public String visit(IntImmediate that, Object d) {
		return "$"+that.getVal();
	}
	
	public String visit(Label that, Object d) {
		return ((d != null)?"":"$")+that.getName();
	}
}